// ts的基本类型约束
// number 类型: 数值类型
let m: number = 18;
m = 20;
console.log(m);

// ts类型检测:在代码编译阶段就开始检查了，而不是等到代码运行阶段才检查。但是，ts的检查结果是不影响最终编译的js代码的，因为所有不合法的ts代码在js里面都是合法的，浏览器执行js都会通过。
function sum(m: number, n: number) {
  return m + n;
}
let aa = sum(1, 2);
console.log(aa);

// 函数返回值类型的约束，直接影响接收这个值的变量
function sum11(a: number, b: number): number {
  return a + b;
}
const n: number = sum11(10, 20);
console.log(n);

// 布尔类型
let isMan: boolean = true;
isMan = false;
console.log("--isMan:", isMan); // --isMan: false

// 字符串类型
let userName: string = "";
userName = "小明";
console.log("--userName:", userName); // --userName: 小明

// 数组类型
let users: number[] = [1, 2, 3, 4, 5, 6];
console.log("---users:", users); // [1, 2, 3, 4, 5, 6]
let users1: string[] = ["1", "2", "3"];
console.log(users1); // ['1', '2', '3']

// 联合类型:由多个基本数据类型组合起来形成的一种类型
let users2: (number | string | boolean)[] = ["1", 18, true, false, 22];

// 数组类型写法一： 类型[]
// 数组类型写法二: Array<类型>
// 注 ： 类型可以是单一类型，也可以是联合类型
let users3: Array<number> = [1, 2, 3, 4, 5, 6];
let users4: Array<string> = ["1", "2", "3"];
let users5: Array<number | string | boolean> = ["1", "2", 20, true];
users5.push(188888);
console.log(users5); // ['1', '2', 20, true, 188888]

// 联合类型：使用 | 符号表示一个变量可以是多种类型
let result: number | boolean | string = "191919";

// 元组类型 ： 一个数据类型和个数已经固定了的数组，后期也能新增，删除，修改，
// [string,number,boolean] 元组类型
let tData: [
  string,
  number,
  boolean,
  number,
  number,
  number,
  number,
  number,
  number
] = ["11", 12, true, 888, 111, 999, 666, 777, 999];
tData.push("1000");
console.log(tData[0], tData); // ['11', 12, true, 888, 111, 999, 666, 777, 999, '1000']

// 枚举类型 ： 它一般用来设置一些常量数据，声明出来的值后续不会发生变化，只拿来使用。

//
enum Sports {
  first = "篮球",
  second = "乒乓球",
  third = "足球",
}
enum classes {
  one = "1班",
  two = "2班",
  three = "3班",
  four = "4班",
  five = "5班",
  six = "6班",
}
console.log(Sports.first); // 篮球
console.log(classes.one); // 1班

// Any类型：任意类型，使用它标识变量，就是让ts编译器忽略这个变量，不检查类型，直接编译成js。一般用在无法确定类型的情况下使用。
let result2: any = "";
result2 = 100;
result2 = "100";

//  void类型：空类型,用在函数的返回值。表示函数没有返回值
function sum2(): void {
  console.log("---------------");
}
sum2(); // ---------------

// null 和 undefined 类型：它俩也是一种类型，和string,number以一样，都是类型。可以用作初始值。
let result3: string | undefined = undefined;
result3 = "小王";
console.log(result3); // 小王

let result4: number[] | null = null;
result4 = [1, 2, 3, 4];
console.log(result4); //[1, 2, 3, 4]

// 类型断言：强制告诉ts编译器，这个变量是什么类型。在一些复杂的场景下，ts已经无法准确推断变量类型了
// 两种语法:(<断言类型>result5)  (result5 as 断言类型)
let result5: unknown;
(<number[]>result5).forEach(item => {
  console.log(item);
});
(result5 as number[]).forEach(item => {
  console.log(item);
})
